home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / MacShell / AECustom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-04  |  8.5 KB  |  352 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:        MacShell
  5. ** File:        AECustom.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. */
  11.  
  12.  
  13.  
  14. /*****************************************************************************/
  15.  
  16.  
  17.  
  18. #include "MacShell.h"            /* Get the MacShell includes/typedefs, etc.    */
  19. #include "MacShellCommon.h"        /* Get the stuff in common with rez.        */
  20. #include "MacShell.protos"        /* Get the prototypes for MacShell.            */
  21.  
  22. #ifndef __ERRORS__
  23. #include <Errors.h>
  24. #endif
  25.  
  26. #ifndef __TEXTEDITCONTROL__
  27. #include "TextEditControl.h"
  28. #endif
  29.  
  30. #ifdef THINK_C
  31. #include "Utilities.h"
  32. #else
  33. #ifndef __UTILITIES__
  34. #include <Utilities.h>
  35. #endif
  36. #endif
  37.  
  38.  
  39.  
  40. /*****************************************************************************/
  41.  
  42.  
  43.  
  44. extern Boolean        gHasAppleEvents;
  45. extern RgnHandle    gCursorRgn;
  46.  
  47. static pascal OSErr        ReceiveMessage(AppleEvent *message, AppleEvent *reply, long refcon);
  48.  
  49.  
  50.  
  51. /*****************************************************************************/
  52.  
  53.  
  54.  
  55. static triplets keywordsToInstall[] = {
  56.     { kCustomEventClass,    keyAppMessage,        (ProcPtr)ReceiveMessage }
  57. };        /* These are the custom AppleEvents. */
  58.  
  59.  
  60.  
  61. /*****************************************************************************/
  62. /*****************************************************************************/
  63.  
  64.  
  65.  
  66. /* InitCustomAppleEvents
  67. **
  68. ** Install our custom AppleEvents.  This is done in addition to installing
  69. ** the required AppleEvents.  InitAppleEvents, which installs the required
  70. ** AppleEvents, must be called first, since it sets up some global values.
  71. */
  72.  
  73. #pragma segment AppleEvents
  74. void    InitCustomAppleEvents(void)
  75. {
  76.     OSErr    err;
  77.     short    i;
  78.  
  79.     if (gHasAppleEvents) {
  80.         for (i = 0; i < (sizeof(keywordsToInstall) / sizeof(triplets)); ++i) {
  81.             err = AEInstallEventHandler(
  82.                 keywordsToInstall[i].theEventClass,    /* What class to install.  */
  83.                 keywordsToInstall[i].theEventID,    /* Keywords to install.    */
  84.                 keywordsToInstall[i].theHandler,    /* The AppleEvent handler. */
  85.                 0L,                                    /* Unused refcon.           */
  86.                 false                                /* Only for our app.       */
  87.             );
  88.  
  89.             if (err) {
  90.                 Alert(rErrorAlert, (ModalFilterProcPtr)alertFilter);
  91.                 return;
  92.             }
  93.         }
  94.     }
  95. }
  96.  
  97.  
  98.  
  99. /*****************************************************************************/
  100.  
  101.  
  102.  
  103. /* SendMessage
  104. **
  105. */
  106.  
  107. #pragma segment AppleEvents
  108. OSErr    SendMessage(FileRecHndl frHndl, short messageType)
  109. {
  110.     AEAddressDesc    remoteLoc;
  111.     OSErr            err;
  112.     AppleEvent        theAevt, reply;
  113.     long            windID[2];
  114.     short            i;
  115.     WindowPtr        oldPort;
  116. #if MACSHELL_VERSION
  117.     TEHandle        te;
  118.     char            hstate;
  119.     Handle            hText;
  120.     long            size;
  121. #endif
  122.  
  123.     if (!(*frHndl)->connect.connected) return(noErr);
  124.  
  125.     oldPort = SetFilePort(frHndl);
  126.  
  127.     theAevt.dataHandle = reply.dataHandle = nil;
  128.         /* Make sure disposing of the descriptors is okay in all cases.
  129.         ** This will not be necessary after 7.0b3, since the calls that
  130.         ** attempt to create the descriptors will nil automatically
  131.         ** upon failure. */
  132.  
  133.     remoteLoc = (*frHndl)->connect.remoteLoc;
  134.  
  135.     err = AECreateAppleEvent(        /* CREATE EMPTY APPLEEVENT.     */
  136.         kCustomEventClass,            /* Event class.                 */
  137.         typeAppMessage,                /* Event ID.                 */
  138.         &remoteLoc,                    /* Address of receiving app. */
  139.         kAutoGenerateReturnID,        /* This value causes the     */
  140.                                     /* AppleEvent manager to     */
  141.                                     /* assign a return ID that     */
  142.                                     /* is unique to the session. */
  143.         kAnyTransactionID,            /* Ignore transaction ID.     */
  144.         &theAevt                    /* Location of event.         */
  145.     );
  146.  
  147.     if (!err) {            /* Say what the message is. */
  148.         AEPutParamPtr(
  149.             &theAevt,
  150.             keyDirectObject,
  151.             typeShortInteger,
  152.             (Ptr)&messageType,
  153.             sizeof(short)
  154.         );
  155.     }
  156.  
  157.     if (!err) {            /* Say what window message is for. */
  158.         for (i = 0; i < 2; ++i) windID[i] = (*frHndl)->connect.windowID[i];
  159.         AEPutParamPtr(
  160.             &theAevt,
  161.             keyWindowID,
  162.             typeDoubleLong,
  163.             (Ptr)&windID[0],
  164.             2 * sizeof(long)
  165.         );
  166.     }
  167.  
  168.     /* The stuff that applies to all messages is now done.  Now specifically
  169.     ** handle all the different message types. */
  170.  
  171.     if (!err) {
  172.         switch (messageType) {
  173.  
  174.             case kDisconnectMssg:
  175.                     /* All the information we need is already in the AppleEvent. */
  176.                 break;
  177.  
  178. #if MACSHELL_VERSION
  179.             case kTextMssg:
  180.                 te     = (*frHndl)->doc.outBox;
  181.                 hText  = (*te)->hText;
  182.                 hstate = LockHandleHigh(hText);
  183.                 size   = (*te)->teLength;
  184.                 err = AEPutParamPtr(
  185.                     &theAevt,
  186.                     keyAppMessage,
  187.                     typeTextMessage,
  188.                     *hText,
  189.                     size
  190.                 );
  191.                 HSetState(hText, hstate);
  192.                 break;
  193. #endif
  194.  
  195.         }
  196.     }
  197.  
  198.     if (!err) {        /* If everything looks good... */
  199.         err = AESend(                    /* SEND APPLEEVENT.                */
  200.             &theAevt,                    /* Our Apple Event to send.        */
  201.             &reply,                        /* We may have a reply.            */
  202.             kAENoReply,                    /* Don't wait for reply.        */
  203.             kAENormalPriority,            /* App. send priority.            */
  204.             0,                            /* We aren't waiting.            */
  205.             nil,                        /* No wait, no filter.            */
  206.             nil                            /* EventFilterProcPtr.            */
  207.         );
  208.     }
  209.  
  210. #if MACSHELL_VERSION
  211.     if (!err) {
  212.         if (messageType == kTextMssg)
  213.             CTESetSelect(0, (*te)->teLength, te);
  214.                 /* Select all the text so entering the next message
  215.                     ** is more convenient. */
  216.     }
  217. #endif
  218.  
  219.     AEDisposeDesc(&theAevt);
  220.     AEDisposeDesc(&reply);
  221.         /* Dispose of the descriptors, created or not.
  222.         ** If not created, no harm done by calling. */
  223.  
  224.     SetPort(oldPort);
  225.     return(err);
  226. }
  227.  
  228.  
  229.  
  230. /*****************************************************************************/
  231.  
  232.  
  233.  
  234. #pragma segment AppleEvents
  235. pascal OSErr    ReceiveMessage(AppleEvent *message, AppleEvent *reply, long refcon)
  236. {
  237. #pragma unused (refcon)
  238.  
  239.     OSErr            err;
  240.     short            messageType;
  241.     WindowPtr        window;
  242.     FileRecHndl        frHndl;
  243.     DescType        actualType;
  244.     long            actualSize, windID[2];
  245.     AEAddressDesc    remoteLoc;
  246. #if MACSHELL_VERSION
  247.     Handle            mssgData;
  248.     char            hstate;
  249.     long            mssgSize;
  250. #endif
  251.  
  252.     err = noErr;
  253.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  254.         reply,                    /* The AppleEvent.              */
  255.         keyReplyErr,            /* AEKeyword                 */
  256.         typeShortInteger,        /* Desired type.             */
  257.         (Ptr)&err,                /* Pointer to area for data. */ 
  258.         sizeof(short)            /* Size of data area.         */
  259.     );
  260.  
  261.     err = AEGetParamPtr(        /* GET THE MESSAGE TYPE.     */
  262.         message,                /* The AppleEvent.              */
  263.         keyDirectObject,        /* AEKeyword                 */
  264.         typeShortInteger,        /* Desired type.             */
  265.         &actualType,            /* Type code.                 */
  266.         (Ptr)&messageType,        /* Pointer to area for data. */ 
  267.         2 * sizeof(long),        /* Size of data area.         */
  268.         &actualSize                /* Returned size of data.     */
  269.     );
  270.  
  271.     if (!err) {
  272.         err = AEGetParamPtr(        /* GET WINDOW MESSAGE IS FOR. */
  273.             message,                /* The AppleEvent.               */
  274.             keyWindowID,            /* AEKeyword                  */
  275.             typeDoubleLong,            /* Desired type.              */
  276.             &actualType,            /* Type code.                  */
  277.             (Ptr)&windID[0],        /* Pointer to area for data.  */ 
  278.             2 * sizeof(long),        /* Size of data area.          */
  279.             &actualSize                /* Returned size of data.      */
  280.         );
  281.     }
  282.  
  283.     if (!err) {            /* See if the requested window exists... */
  284.         if (window = GetAEWindow(windID[1], windID[0])) {
  285.             frHndl = (FileRecHndl)GetWRefCon(window);
  286.                 /* The window still exists... */
  287.         }
  288.         else
  289.             err = userCanceledErr;
  290.                 /* User (or computer) canceled connection by disconnecting improperly. */
  291.     }
  292.  
  293.     if (!err) {        /* If everything is cool, then do the specific task... */
  294.  
  295.         switch(messageType) {
  296.  
  297.             case kDisconnectMssg:
  298.                 remoteLoc = (*frHndl)->connect.remoteLoc;
  299.                 AEDisposeDesc(&remoteLoc);
  300.                 (*frHndl)->connect.connected = false;
  301.                 AdjustMenus();
  302.                 break;
  303.  
  304. #if MACSHELL_VERSION
  305.             case kTextMssg:
  306.                 if (!err) {        /* Determine the size of the data... */
  307.                     err = AEGetParamPtr(
  308.                         message,                /* The AppleEvent.              */
  309.                         keyAppMessage,            /* AEKeyword                 */
  310.                         typeTextMessage,        /* Desired type.             */
  311.                         &actualType,            /* Type code.                 */
  312.                         nil,                    /* Pointer to area for data. */ 
  313.                         0,                        /* Size of data area.         */
  314.                         &mssgSize                /* Returned size of data.     */
  315.                     );
  316.                 }
  317.                 mssgData = nil;
  318.                 if (!err) {        /* Get the data... */
  319.                     mssgData = NewHandle(mssgSize);
  320.                     if (mssgData) {
  321.                         hstate = LockHandleHigh(mssgData);
  322.                         err = AEGetParamPtr(
  323.                             message,                /* The AppleEvent.              */
  324.                             keyAppMessage,            /* AEKeyword                 */
  325.                             typeTextMessage,        /* Desired type.             */
  326.                             &actualType,            /* Type code.                 */
  327.                             *mssgData,                /* Pointer to area for data. */ 
  328.                             mssgSize,                /* Size of data area.         */
  329.                             &actualSize                /* Returned size of data.     */
  330.                         );
  331.                     }
  332.                     else err = memFullErr;
  333.                 }
  334.                 if (!err) {
  335.                     BeginContent(window);
  336.                     mssgData = CTESwapText((*frHndl)->doc.inBox, mssgData, true);
  337.                     EndContent(window);
  338.                 }
  339.                 if (mssgData) DisposHandle(mssgData);
  340.                 if (!err) NotifyUser();
  341.                 break;
  342. #endif
  343.  
  344.         }
  345.     }
  346.  
  347.     return(err);
  348. }
  349.  
  350.  
  351.  
  352.